package com.haiya.oauth.controller;

import com.haiya.common.request.Query;
import com.haiya.common.response.CommonRes;
import com.haiya.oauth.service.ITokensService;
import com.haiya.common.constant.SecurityConstants;
import com.haiya.oauth2.util.AuthUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * token管理接口
 *
 * @author qiaoguoqiang
 */
@Api(tags = "Token管理")
@Slf4j
@RestController
@RequestMapping("/tokens")
public class TokensController {
    @Resource
    private ITokensService tokensService;

    @Resource
    private ClientDetailsService clientDetailsService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @GetMapping("")
    @ApiOperation(value = "token列表")
    public CommonRes list(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        return CommonRes.ok(tokensService.queryList(query));
    }

    /**
     * 获取jwt密匙，从请求header的 Authorization 值中解析出clientId和clientSecret。
     * Authorization格式: "Basic xxxxxxzzzasdf", 其中Basic后面的字符串是通过下面的方式得到:
     * javascript中的实现:
     *
     * window.btoa(clientId + ":" + clientSecret)
     *
     * btoa和atob是window对象的两个函数，其中btoa是binary to ascii，用于将binary的数据用ascii码表示，即Base64的编码过程
     * 而atob则是ascii to binary，用于将ascii码解析成binary数据
     *
     * 对应Java中的实现，后续补充进来。
     * @param request
     * @return
     */
    @GetMapping("/key")
    @ApiOperation(value = "获取jwt密钥")
    public CommonRes key(HttpServletRequest request) {
        try {
            String[] clientArr = AuthUtils.extractClient(request);
            ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientArr[0]);
            if (clientDetails == null || !passwordEncoder.matches(clientArr[1], clientDetails.getClientSecret())) {
                throw new BadCredentialsException("应用ID或密码错误");
            }
        } catch (AuthenticationException ae) {
            return CommonRes.error(ae.getMessage());
        }
        org.springframework.core.io.Resource res = new ClassPathResource(SecurityConstants.RSA_PUBLIC_KEY);
        try (BufferedReader br = new BufferedReader(new InputStreamReader(res.getInputStream()))) {
            return CommonRes.ok(br.lines().collect(Collectors.joining("\n")));
        } catch (IOException ioe) {
            log.error("key error", ioe);
            return CommonRes.error(ioe.getMessage());
        }
    }
}
